#include <iostream>
#include <vector>
#include <functional>
using namespace std;

// 计算简单环的数量
int countSimpleCycles(int n, const vector<pair<int, int>> &edges)
{
	// 构建邻接表
	vector<vector<int>> adj(n);
	for (const auto &edge : edges) {
		int u = edge.first;
		int v = edge.second;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int count = 0;
	vector<bool> visited(n, false); // 记录当前路径中的顶点

	// DFS递归函数
	function<void(int, int, int)> dfs = [&](int current, int start, int length) {
		for (int neighbor : adj[current]) {
			if (neighbor == start) {
				// 找到环，且长度至少为3（当前路径长度+1 >=3 → length >=2）
				if (length >= 2) {
					count++;
				}
			}
			// 仅访问编号大于起点且未被访问的顶点，避免重复计数
			else if (neighbor > start && !visited[neighbor]) {
				visited[neighbor] = true;
				dfs(neighbor, start, length + 1);
				visited[neighbor] = false; // 回溯
			}
		}
	};

	// 对每个顶点作为起点（最小顶点）进行搜索
	for (int v = 0; v < n; v++) {
		visited[v] = true;
		// 只从编号大于v的邻居开始，确保v是路径中最小的顶点
		for (int w : adj[v]) {
			if (w > v) {
				visited[w] = true;
				dfs(w, v, 1); // 路径长度：v到w为1步
				visited[w] = false; // 回溯
			}
		}
		visited[v] = false; // 回溯
	}

	// 每个环被两个方向各计数一次，因此除以2
	return count / 2;
}

// 示例测试
int main()
{
	vector<pair<int, int>> edges;
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		edges.push_back({ --u, --v });
	}
	cout << countSimpleCycles(n, edges) << endl;
	return 0;
}
